/*提供对动画的封装*/
function Animation(texture,width,hight,number,duration,isAixY){
    /*
     * @param {cc.TextureCache} Animation texture
     * @param {Number} Frame width
     * @param {Number} Frame hight
     * @param {Number} Frame number
     * @param {Duration} Animation duration time
     * @param {bool} (Option) Is split with y aix
     */
    this.duration = duration;
    this.frameNumber = number;
    this.handler = null;
    this.repeat_times = 0;
    this._cb= null;
    var frameArray = [];
    for(var i = 0;i < number; ++i){
        var frame = null;
        if(isAixY){
            frame = cc.SpriteFrame.createWithTexture(texture, cc.rect(0,i*hight,width,hight));
        }else{
            frame = cc.SpriteFrame.createWithTexture(texture,cc.rect(i*width,0,width,hight));
        }
        frameArray.push(frame);
    }
    this.animationObj = cc.Animation.create(frameArray,duration/number);
    this.sprite = cc.Sprite.createWithSpriteFrame(frameArray[0]);
};

Animation.createAnimationFromFile = function(filename,width,hight,number,duration,isAixY){
    return new Animation(cc.TextureCache.getInstance().addImage(filename),width,hight,number,duration,isAixY);
};

/* play animation
 * @param {Number}repeat time, -1 for forever
 * * @parame {cc.Animation} Animation object
 *  */
Animation.prototype.playAnimationObj = function(times,animationObj){
    var self = this;
    var repeate_duration = this.duration;
    self.sprite.runAction(cc.Animate.create(animationObj));
    this.handler = setInterval(function(){
        if(times !== -1 && ++self.repeat_times >= times){
            self.stop();
            return;
        }
        self.sprite.runAction(cc.Animate.create(animationObj));
    },repeate_duration * 1000);
};


/* play animation
* @param {Number} (Option)repeat time, -1 for forever
* @param {Number} (Option)delay time for every times play over
 *  */
Animation.prototype.play = function(){
    var times = 1;
    if(arguments.length > 0){
        times = arguments[0];
    }
    if(arguments.length > 1 ){
        repeate_duration += arguments[1];
    }
    this.playAnimationObj(times,this.animationObj);
};


/*stop repeat play
* */
Animation.prototype.stop = function(){
    if(this.handler){
        clearInterval(this.handler);
        this.handler = null;
        this.repeat_times = 0;
        if(this._cb){
            this._cb();
        }
    }
};
/*set play over callback
* */
Animation.prototype.onplayover = function(cb){
    this._cb = cb;
};

/*<static> create animation by animation name
* */
Animation.createByName = function(name){
    if(g_ClientConfig.animations.hasOwnProperty(name))
    {
        var args = g_ClientConfig.animations[name];
        return Animation.createAnimationFromFile(args.filename,args.width,args.height,args.frame_number,args.duration);
    }
    return null;
};

Animation.prototype.getSprite = function(){
    return this.sprite;
};

/*Movement is a player moved with shadow
*@param {String} actor_animation_name
*@param {String} shadowname
* */
function Movement(actor_animation_name,shadowname){
    this.actor_animation = Animation.createByName(actor_animation_name);
    this.shadow_animation = Animation.createByName(shadowname);
    this.actor_sprite = this.actor_animation.sprite;
    this.shadow_sprite = this.shadow_animation.sprite;
    this.shadow_sprite.setAnchorPoint(cc.p(0,0));
    this.shadow_sprite.setPosition(cc.p(0,0));

    this.actor_sprite.setVertexZ(10);
    this.shadow_sprite.setVertexZ(0);

    this.actor_sprite.addChild(this.shadow_sprite,-1);

}

Movement.prototype.getDuration = function(){
    return this.actor_animation.duration;
};

Movement.prototype.getSprite = function(){
    return this.actor_sprite;
};

Movement.prototype.play = function(){
    this.actor_animation.play.apply(this.actor_animation,arguments);
    this.shadow_animation.play.apply(this.shadow_animation,arguments);
};

Movement.prototype.stop = function(){
    this.actor_animation.stop.apply(this.actor_animation,arguments);
    this.shadow_animation.stop.apply(this.shadow_animation,arguments);
};

Movement.prototype.onplayover = function(cb){
    var flag= false;
    function checkStop(){
        if(flag){
            if(typeof cb == "function"){
                cb();
            }
        }else{
            flag = true;
        };
    };
    this.actor_animation.onplayover(function(){
        checkStop();
    });
    this.shadow_animation.onplayover(function(){
        checkStop();
    });
};

/*
 *  */
function PlayerActionSet(parent,stand_pos,move_pos,id,isEnemy){
    this._stand_pos = stand_pos;
    this._move_pos = move_pos;
    this.current_action = null;
    this.current_postion = null;
    this.parent = parent;
    this.id = id;
    this.isEnemy = isEnemy;
}

PlayerActionSet.prototype.createMovement = function(name){
    var prefix = "player";
    if(this.isEnemy){
        prefix = "enemy";
    }
    return new Movement(prefix + "_" + name + "_" + this.id,prefix + "_" + name + "_shadow_" + this.id);
}

PlayerActionSet.prototype.clean = function(){
    if(this.current_action){
        this.current_action.stop();
        this.parent.removeChild(this.current_action.getSprite());
        this.current_action = null;
    }
};

PlayerActionSet.prototype.runNext = function(cb){
    if(!this.current_action){
        cb();
        return;
    }
    var self = this;
    this.current_action.onplayover(function(){
        self.parent.removeChild(self.current_action.getSprite());
        self.current_action = null;
        cb();
    });
    this.current_action.stop();
}

PlayerActionSet.prototype.attachAnimation = function(animation,anchor_pos){
    animation.sprite.setAnchorPoint(anchor_pos);
    animation.sprite.setPosition(cc.p(0,0));
    this.current_action.getSprite().addChild(animation.sprite);
    var self = this;
    animation.onplayover(function(){
        self.current_action.getSprite().removeChild(animation.sprite);
    });
    animation.play(1);
};

PlayerActionSet.prototype.stand = function(){
    this.clean();
    this.current_action = this.createMovement("stand");
    this.current_action.getSprite().setPosition(this._stand_pos);
    this.parent.addChild(this.current_action.getSprite());
    this.current_action.play(-1);
};

PlayerActionSet.prototype.move = function(cb){
    this.clean();
    this.current_action = this.createMovement("move");
    this.current_action.getSprite().setPosition(this._stand_pos);
    this.parent.addChild(this.current_action.getSprite());
    this.current_action.getSprite().runAction(cc.MoveTo.create(this.current_action.getDuration(),this._move_pos));
    this.current_action.onplayover(cb);
    this.current_action.play(1);

};

PlayerActionSet.prototype.fight = function(cb){
    this.clean();
    this.current_action = this.createMovement("fight");
    this.current_action.getSprite().setPosition(this._move_pos);
    this.parent.addChild(this.current_action.getSprite());
    this.current_action.onplayover(cb);
    this.current_action.play(1);
};

PlayerActionSet.prototype.damaged = function(cb){
    this.clean();
    this.current_action = this.createMovement("damaged");
    this.current_action.getSprite().setPosition(this._stand_pos);
    this.parent.addChild(this.current_action.getSprite());
    this.current_action.onplayover(cb);
    this.current_action.play(1);
    var effect = Animation.createByName("damage_effect");
    this.attachAnimation(effect,cc.p(-0.85,-0.65));
};

PlayerActionSet.prototype.defense = function(cb){
    this.clean();
    this.current_action = this.createMovement("defense");
    this.current_action.getSprite().setPosition(this._stand_pos);
    this.parent.addChild(this.current_action.getSprite());
    this.current_action.onplayover(cb);
    this.current_action.play(1);
};

PlayerActionSet.prototype.draw = function(cb){
    var draw_pos = cc.p((this._move_pos.x - this._stand_pos.x)/3 + this._stand_pos.x,(this._move_pos.y - this._stand_pos.y)/3  + this._stand_pos.y);
    this.clean();
    this.current_action = this.createMovement("move");
    this.current_action.getSprite().setPosition(this._stand_pos);
    this.parent.addChild(this.current_action.getSprite());
    this.current_action.getSprite().runAction(cc.MoveTo.create(this.current_action.getDuration(),draw_pos));
    var self = this;
    this.current_action.onplayover(function(){
        self.clean();
        self.current_action = self.createMovement("fight");
        self.current_action.getSprite().setPosition(draw_pos);
        self.parent.addChild(self.current_action.getSprite());
        self.current_action.onplayover(cb);
        self.current_action.play(1);
        //特效只挂在enemy上
        if(self._move_pos.x < self._stand_pos.x){
            var effect = Animation.createByName("draw_effect");
            self.attachAnimation(effect,cc.p(0,0));
        }
    });
    this.current_action.play(1);
};

PlayerActionSet.prototype.getDuration = function(name){
    var prefix = "player";
    if(this.isEnemy){
        prefix = "enemy";
    }
    var animation_name = prefix + "_" + name + "_" + this.id;
    return g_ClientConfig.animations[name].duration;
};